/**
 * @author 2404559603@qq.com
 * @time 2022-04-18 17:40 PM
 * @description 路由定义
 */

/** 插件注册 */
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

/** 引入store实例 */
import store from '../store'

/** 解决push的错误方法，需要重写push方法 */
const pushPlugin = Router.prototype.push
Router.prototype.push = function(_params) {
    // console.log('----------------- push方法');
    pushPlugin.call(this, _params).catch(e => {
        // console.log('------------------------ 重写push')
        // console.log(e)   
    })
}

/** 路由组件注册 */
// import Login from '../pages/login'
// import Register from '../pages/login/Register'
// import Home from '../pages/home'
/**
 * 为了解决首次加载的速度和性能，所以路由组件都应该动态加载(懒加载)
 * 懒加载：是一个方法，这个方法返回引入的文件对象
 */
const Login = () => import('../pages/login/index.vue') // 登录
const Register = () => import('../pages/login/Register') // 注册


const Home = () => import('../pages/index/container.vue') // 首页容器
const Index = () => import('../pages/index/index.vue') // 首页
const Cart = () => import('../pages/cart') // 购物车
const Details = () => import('../pages/details/index.vue') // 详情
const Around = () => import('../pages/details/around.vue') // 详情
const Move = () => import('../pages/details/move.vue') // 详情
const Recommend = () => import('../pages/recommend')  // 推荐
const Type = () => import('../pages/index/type.vue')  // 分类信息

// const Address = () => import('../pages/address/index.vue')  // 地址管理

const Me = () => import('../pages/me/index.vue')  // 我的
const EditMe = () => import('../pages/me/edit.vue')  // 修改个人信息
const myAddress = () => import('../pages/me/myAddress.vue')  // 修改我的地址
const myGoods = () => import('../pages/me/myGoods.vue')  // 修改个人信息
const other = () => import('../pages/me/other.vue')  // 修改个人信息




/** 实例化 */
const router = new Router({
    mode:'history',
    /**
     * 路由模式：hash、history模式
     * hash模式是监听hashchange事件来实现的
     * history模式需要后端支持(因为地址是一个get请求)，所有定义的路由，后端不能返回数据，应该返回index.html页面
     */
    // mode: 'history',
    routes: [
        {path:'', redirect:'/login'},
        {path: '/login', component: Login, meta: {needLogin: false}}, // 登录
        {path: '/register', component: Register, meta: {needLogin: false}}, //注册
        {
            path:'/index',
            component:Home,
            meta: {needLogin: false},
            redirect:'/index/home',
            children:[
                {path: 'home', component: Index}, // 首页
                {path: 'cart', component: Cart}, // 购物车
                
                {path: 'recommend', component: Recommend}, // 推荐路由
                {path: 'me', component: Me},  // 我的
                
            ]
        },
        {path:'/edit', component:EditMe}, // 我的修改信息页面
        {path:'/goods', component:myGoods}, // 我的订单
        {path:'/address', component:myAddress}, // 我的地址
        {path:'/other', component:other}, // 我的其他

        {path: '/details', name:'details', component: Details},  // 商品详情页面
        {path: '/detailsAround', name:'around', component: Around},  // 商品详情页面
        {path: '/detailsMove/:id', name:'move', component: Move},  // 商品详情页面
        {path:'/type/:type', name:"type", component:Type}, // 分类页面
        // {path:'/address', component:Address} // 地址管理页面
    ]
})

/** 需要实现路由权限全局拦截 */
const roleCallback = function(to, from, next) {
    /**
     * 权限拦截
     * 1. 判断是否需要权限拦截 -- 在路由上可以确认一个固定参数(meta)
     * 2. 要在系统中获取一个用于权限判断的标识 -- 使用token(缓存在vuex中，这里需要调用vuex的数据)
     * 3. 如果权限不够，需要重定向到login页面
     */
    let needLogin = to.meta.needLogin
    if (needLogin === false) {
        next()
        return
    }
    
    /**
     * 从vuex中获取token数据
     * 因为这个文件是一个js文件，并且不是一个vue组件，那么就没有this.$store
     * 又因为this.$store是store实例对象，那么可以直接引入store实例
     */
    let flag = store.getters['common/token']
    if (!!flag) {
        next()
        return
    }

    /**
     * Uncaught (in promise) Error: Redirected when going from "/login" to "/home" via a navigation guard.
     * 未捕获Promise异常(catch分支)，因为从login页面去home页面，然后被拦截，又重新定向到login页面，这个是不合理的
     * 首先这个错误是：是push方法引起的，得到push方法是一个promise，push是router实例的方法，所以是Router类的原型方法
     */
    alert('该路由需要登录才可以进入，所以你看见我了')
    next('/login')
}
router.beforeEach(roleCallback)

/** 导出路由实例对象 */
export default router